package com.jhgsys.internal.sypq.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.jhgsys.internal.common.exception.FebsException;
import com.jhgsys.internal.common.utils.DateUtil;
import com.jhgsys.internal.common.utils.UploadPathUtil;
import com.jhgsys.internal.dict.service.IDictService;
import com.jhgsys.internal.sypq.entity.*;
import com.jhgsys.internal.sypq.mapper.*;
import com.jhgsys.internal.sypq.params.FileParams;
import com.jhgsys.internal.sypq.params.OutFinishParams;
import com.jhgsys.internal.sypq.params.ShipModelProcParams;
import com.jhgsys.internal.sypq.params.WechatModelParams;
import com.jhgsys.internal.sypq.service.IModelShipService;
import com.jhgsys.internal.common.entity.QueryRequest;
import com.jhgsys.internal.common.utils.FebsUtil;
import com.jhgsys.internal.sypq.service.IProjectManagerService;
import com.jhgsys.internal.sypq.service.ISypqProjectService;
import com.jhgsys.internal.sypq.utils.WordUtils;
import com.jhgsys.internal.sypq.vo.CurUserProjInfoVO;
import com.jhgsys.internal.sypq.vo.ModelShipProcsVO;
import com.jhgsys.internal.sypq.vo.ProjectVO;
import com.jhgsys.internal.sypq.vo.WechatShipModelVO;
import com.jhgsys.internal.system.entity.User;
import com.jhgsys.internal.system.entity.UserRole;
import com.jhgsys.internal.system.service.IUserRoleService;
import com.jhgsys.internal.system.service.IUserService;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import com.jhgsys.internal.common.entity.FebsConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.annotation.Propagation;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.toolkit.StringPool;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import java.io.*;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 船模 Service实现
 *
 * @author ganjun
 * @date 2024-11-13 19:03:49
 */
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class ModelShipServiceImpl extends ServiceImpl<ModelShipMapper, ModelShip> implements IModelShipService {

    @Resource
    private IDictService dictService;

    @Resource
    private ModelShipProcessMapper modelShipProcessMapper;

    @Resource
    private AttachmentFileMapper attachmentFileMapper;

    @Resource
    private ModelShipTestMapper modelShipTestMapper;

    @Resource
    private ISypqProjectService projectService;

    @Resource
    private IUserService userService;

    @Autowired
    IProjectManagerService projectManagerService;

    @Autowired
    private IUserRoleService userRoleService;

    @Autowired
    private TaskMapper taskMapper;

    @Autowired
    private SypqProjectMapper projectMapper;

    /**
     * 查询（分页）
     * @author ganjun
     * @date 2024-11-13 19:03:49
     * @param request QueryRequest
     * @param modelShip modelShip
     * @return IPage<ModelShip>
    */
    @Override
    public IPage<ModelShip> findModelShipPage(QueryRequest request, String demondFinishTime, String name, String statusSearch, String shipCode) {
        LambdaQueryWrapper<ModelShip> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ModelShip::getDeletedFlg, 0);
        queryWrapper.orderByDesc(ModelShip::getCreatedTime);
        //名称
        if(StringUtils.isNotBlank(name)){
            queryWrapper.like(ModelShip::getProjectName, name);
        }

        //要求完成时间
        if(StringUtils.isNotBlank(demondFinishTime)){
            String[] times = demondFinishTime.split(" - ");
            queryWrapper.between(ModelShip::getDemandEnddate, times[0], times[1]);
        }
        //状态
        if(StringUtils.isNotBlank(statusSearch)){
            queryWrapper.eq(ModelShip::getStatus, statusSearch);
        }
        //船模编号
        if(StringUtils.isNotBlank(shipCode)){
            queryWrapper.eq(ModelShip::getShipCode, shipCode);
        }

        //角色判断
        CurUserProjInfoVO curUserProjInfoVO = getCurUserProjInfo();
        boolean isSysAdmin = curUserProjInfoVO.isSysAdmin();
        List<String> projCodeList = curUserProjInfoVO.getProjCodeList();
        //根据权限判断可以查看的项目相关的桨模
        if(!isSysAdmin){
            if(CollectionUtil.isNotEmpty(projCodeList)){
                queryWrapper.in(ModelShip::getProjectCode, projCodeList);
            }else{
                projCodeList.add("0");
                queryWrapper.in(ModelShip::getProjectCode, projCodeList);
            }
        }

        Page<ModelShip> page = new Page<>(request.getPageNum(), request.getPageSize());
        FebsUtil.pageWrapper(page, request);
        return this.page(page, queryWrapper);
    }

    @Override
    public List<ModelShip> export(QueryRequest request, String demondFinishTime, String name, String statusSearch, String shipCode){
        LambdaQueryWrapper<ModelShip> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ModelShip::getDeletedFlg, 0);
        queryWrapper.orderByDesc(ModelShip::getCreatedTime);
        //项目名称
        if(StringUtils.isNotBlank(name)){
            queryWrapper.like(ModelShip::getProjectName, name);
        }

        //要求完成时间
        if(StringUtils.isNotBlank(demondFinishTime)){
            String[] times = demondFinishTime.split(" - ");
            queryWrapper.between(ModelShip::getDemandEnddate, times[0], times[1]);
        }
        //状态
        if(StringUtils.isNotBlank(statusSearch)){
            queryWrapper.eq(ModelShip::getStatus, statusSearch);
        }
        //船模编号
        if(StringUtils.isNotBlank(shipCode)){
            queryWrapper.eq(ModelShip::getShipCode, shipCode);
        }
        return this.baseMapper.selectList(queryWrapper);
    }

    /**
     * 查询（所有）
     * @author ganjun
     * @date 2024-11-13 19:03:49
     * @param modelShip modelShip
     * @return List<ModelShip>
     */
    @Override
    public List<ModelShip> findModelShipList(ModelShip modelShip) {
	    LambdaQueryWrapper<ModelShip> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ModelShip::getDeletedFlg, 0);
		if(StringUtils.isNotEmpty(modelShip.getShipCode())){
            queryWrapper.eq(ModelShip::getShipCode, modelShip.getShipCode());
        }
        if(StringUtils.isNotEmpty(modelShip.getProjectCode())){
            queryWrapper.eq(ModelShip::getProjectCode, modelShip.getProjectCode());
        }
		return this.baseMapper.selectList(queryWrapper);
    }

    /**
    * 根据ID查询
    * @author ganjun
    * @date 2024-11-13 19:03:49
    * @param id
    * @return ModelShip
    */
    @Override
    public ModelShip findModelShipById(String id){
        return this.baseMapper.selectById(id);
    }

    /**
     * 新增
     * @author ganjun
     * @date 2024-11-13 19:03:49
     * @param modelShip modelShip
     */
    @Override
    @Transactional
    public boolean createModelShip(ModelShip modelShip) {
        modelShip.setStatusName(dictService.findDictLabel("MODEL_SHIP_PROCESS_STATUS", "1"));
        modelShip.setStatus(1);
        modelShip.setDeletedFlg("0");
        return this.save(modelShip);
    }

    /**
     * 修改
     * @author ganjun
     * @date 2024-11-13 19:03:49
     * @param modelShip modelShip
     */
    @Override
    @Transactional
    public boolean updateModelShip(ModelShip modelShip) {
        return this.updateById(modelShip);
    }


    @Override
    @Transactional
    public boolean outFinish(OutFinishParams params) {
        //根据id获取船模信息
        ModelShip modelShip = this.baseMapper.selectById(params.getId());
        modelShip.setStatus(9);
        modelShip.setStatusName(dictService.findDictLabel("MODEL_SHIP_PROCESS_STATUS", "9"));
        modelShip.setActuallyStartdate(params.getActuallyStartdate());
        modelShip.setActuallyEnddate(params.getActuallyEnddate());
        return this.updateById(modelShip);
    }

    /**
     * 逻辑删除
     * @author ganjun
     * @date 2024-11-13 19:03:49
     * @param modelShip modelShip
     * @param modelShipIds modelShipIds
     */
    @Override
    @Transactional
    public boolean deleteModelShip(ModelShip modelShip,String modelShipIds) {
        boolean result = false;
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        List<String> list = Arrays.asList(modelShipIds.split(StringPool.COMMA));

        modelShip.setDeletedBy(user.getUserName());
        modelShip.setDeletedTime(new Date());
        modelShip.setDeletedFlg(FebsConstant.INVALID);
        int update = this.baseMapper.update(modelShip,new LambdaQueryWrapper<ModelShip>().in(ModelShip::getId,list));
        if (update > 0 ){
            result = true;
        }
        return result;
	}

    /**
    * 物理删除
    * @author ganjun
    * @date 2024-11-13 19:03:49
    * @param modelShipIds modelShipIds
    */
    @Override
    @Transactional
    public boolean physicallyDeleteModelShip(String modelShipIds) {
        List<String> list = Arrays.asList(modelShipIds.split(StringPool.COMMA));
        LambdaQueryWrapper<ModelShip> wapper = new LambdaQueryWrapper<>();
        wapper.in(ModelShip::getId,list);
        return this.remove(wapper);
    }


    @Override
    @Transactional
    public void startProc(ShipModelProcParams params){
        //根据id获取船模信息
        ModelShip modelShip = this.baseMapper.selectById(params.getId());
        modelShip.setActuallyStartdate(params.getActuallyStartdate());
        modelShip.setStatus(2);
        modelShip.setStatusName(dictService.findDictLabel("MODEL_SHIP_PROCESS_STATUS", "2"));
        this.updateModelShip(modelShip);
        //添加加工过程
        ModelShipProcess proc = new ModelShipProcess();
        proc.setShipId(modelShip.getId());
        proc.setShipCode(modelShip.getShipCode());
        proc.setStartDate(params.getActuallyStartdate());
        proc.setProcessStatus(1);
        proc.setItem("开始");
        proc.setOperator(params.getOperator());
        User user = userService.findById(params.getOperator());
        if(user != null){
            proc.setOperatorName(user.getUname());
        }
        modelShipProcessMapper.insert(proc);
    }

    @Override
    @Transactional
    public void uploadChart(ShipModelProcParams params){
        //根据id获取船模信息
        ModelShip modelShip = this.baseMapper.selectById(params.getId());

        ModelShipProcess proc = null;
        //获取是否做过上传图纸操作
        LambdaQueryWrapper<ModelShipProcess> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ModelShipProcess::getDeletedFlg, 0);
        queryWrapper.eq(ModelShipProcess::getProcessStatus, 2);
        queryWrapper.eq(ModelShipProcess::getShipId, modelShip.getId());
        proc = modelShipProcessMapper.selectOne(queryWrapper);
        if(proc != null){
            modelShipProcessMapper.updateById(proc);
            //删除原附件，上传新附件
            AttachmentFile attachmentFile = new AttachmentFile();
            attachmentFile.setDeletedFlg(FebsConstant.INVALID);
            User user = (User) SecurityUtils.getSubject().getPrincipal();
            attachmentFile.setDeletedBy(user.getUserName());
            attachmentFile.setDeletedTime(new Date());
            LambdaQueryWrapper<AttachmentFile> fileQueryWrapper = new LambdaQueryWrapper<>();
            fileQueryWrapper.eq(AttachmentFile::getDeletedFlg, 0);
            fileQueryWrapper.eq(AttachmentFile::getVoucherCode, modelShip.getId());
            fileQueryWrapper.eq(AttachmentFile::getVoucherType, "4");
            attachmentFileMapper.update(attachmentFile, fileQueryWrapper);
            //添加附件记录
            List<FileParams> files = params.getFileList();
            if(CollectionUtil.isNotEmpty(files)){
                for(FileParams file : files){
                    AttachmentFile attach = new AttachmentFile();
                    attach.setFilename(file.getFileName());
                    attach.setFilepath(file.getFilePath());
                    //4：代表船模附件
                    attach.setVoucherType("4");
                    attach.setVoucherCode(modelShip.getId());
                    attachmentFileMapper.insert(attach);
                }
            }

        }else{
            modelShip.setStatus(3);
            modelShip.setStatusName(dictService.findDictLabel("MODEL_SHIP_PROCESS_STATUS", "3"));
            this.updateModelShip(modelShip);
            //添加加工过程
            proc = new ModelShipProcess();
            proc.setShipId(modelShip.getId());
            proc.setShipCode(modelShip.getShipCode());
            proc.setStartDate(params.getUploadChartTime());
            proc.setEndDate(params.getUploadChartTime());
            proc.setProcessStatus(2);
            proc.setItem("上传图纸");
            proc.setOperator(params.getOperator());
            User user = userService.findById(params.getOperator());
            if(user != null){
                proc.setOperatorName(user.getUname());
            }
            modelShipProcessMapper.insert(proc);
            //添加附件记录
            List<FileParams> files = params.getFileList();
            if(CollectionUtil.isNotEmpty(files)){
                for(FileParams file : files){
                    AttachmentFile attach = new AttachmentFile();
                    attach.setFilename(file.getFileName());
                    attach.setFilepath(file.getFilePath());
                    //4：代表船模附件
                    attach.setVoucherType("4");
                    attach.setVoucherCode(modelShip.getId());
                    attachmentFileMapper.insert(attach);
                }
            }
        }
    }


    /**
     * 下料
     * @param params
     */
    @Override
    @Transactional
    public void cutting(ShipModelProcParams params){
        //根据id获取船模信息
        ModelShip modelShip = this.baseMapper.selectById(params.getId());
        modelShip.setStatus(4);
        modelShip.setStatusName(dictService.findDictLabel("MODEL_SHIP_PROCESS_STATUS", "4"));
        this.updateModelShip(modelShip);
        //获取上一结点完成时间
        LambdaQueryWrapper<ModelShipProcess> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ModelShipProcess::getDeletedFlg, 0);
        queryWrapper.eq(ModelShipProcess::getProcessStatus, 2);
        queryWrapper.eq(ModelShipProcess::getShipId, modelShip.getId());
        ModelShipProcess lastProc = modelShipProcessMapper.selectOne(queryWrapper);
        //添加加工过程
        ModelShipProcess proc = new ModelShipProcess();
        proc.setShipId(modelShip.getId());
        proc.setShipCode(modelShip.getShipCode());
        proc.setStartDate(lastProc.getEndDate());
        proc.setEndDate(params.getCutTime());
        proc.setProcessStatus(3);
        proc.setItem("下料");
        proc.setOperator(params.getCutOperator());
        User user = userService.findById(params.getCutOperator());
        if(user != null){
            proc.setOperatorName(user.getUname());
        }
        modelShipProcessMapper.insert(proc);
    }

    /**
     * 粗切
     * @param params
     */
    @Override
    @Transactional
    public void routhCut(ShipModelProcParams params){
        //根据id获取船模信息
        ModelShip modelShip = this.baseMapper.selectById(params.getId());
        modelShip.setStatus(5);
        modelShip.setStatusName(dictService.findDictLabel("MODEL_SHIP_PROCESS_STATUS", "5"));
        this.updateModelShip(modelShip);
        //获取上一结点完成时间
        LambdaQueryWrapper<ModelShipProcess> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ModelShipProcess::getDeletedFlg, 0);
        queryWrapper.eq(ModelShipProcess::getProcessStatus, 3);
        queryWrapper.eq(ModelShipProcess::getShipId, modelShip.getId());
        ModelShipProcess lastProc = modelShipProcessMapper.selectOne(queryWrapper);
        //添加加工过程
        ModelShipProcess proc = new ModelShipProcess();
        proc.setShipId(modelShip.getId());
        proc.setShipCode(modelShip.getShipCode());
        proc.setStartDate(lastProc.getEndDate());
        proc.setEndDate(params.getRoughCutTime());
        proc.setProcessStatus(4);
        proc.setItem("粗切");
        proc.setOperator(params.getRoughCutOperator());
        User user = userService.findById(params.getRoughCutOperator());
        if(user != null){
            proc.setOperatorName(user.getUname());
        }
        modelShipProcessMapper.insert(proc);
    }

    /**
     * 精切
     * @param params
     */
    @Override
    @Transactional
    public void fineCut(ShipModelProcParams params){
        //根据id获取船模信息
        ModelShip modelShip = this.baseMapper.selectById(params.getId());
        modelShip.setStatus(6);
        modelShip.setStatusName(dictService.findDictLabel("MODEL_SHIP_PROCESS_STATUS", "6"));
        this.updateModelShip(modelShip);
        //获取上一结点完成时间
        LambdaQueryWrapper<ModelShipProcess> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ModelShipProcess::getDeletedFlg, 0);
        queryWrapper.eq(ModelShipProcess::getProcessStatus, 4);
        queryWrapper.eq(ModelShipProcess::getShipId, modelShip.getId());
        ModelShipProcess lastProc = modelShipProcessMapper.selectOne(queryWrapper);
        //添加加工过程
        ModelShipProcess proc = new ModelShipProcess();
        proc.setShipId(modelShip.getId());
        proc.setShipCode(modelShip.getShipCode());
        proc.setStartDate(lastProc.getEndDate());
        proc.setEndDate(params.getFineCutTime());
        proc.setProcessStatus(5);
        proc.setItem("精切");
        proc.setOperator(params.getFineCutOperator());
        User user = userService.findById(params.getFineCutOperator());
        if(user != null){
            proc.setOperatorName(user.getUname());
        }
        modelShipProcessMapper.insert(proc);
    }

    /**
     * 修模
     * @param params
     */
    @Override
    @Transactional
    public void modRepair(ShipModelProcParams params){
        //根据id获取船模信息
        ModelShip modelShip = this.baseMapper.selectById(params.getId());
        modelShip.setStatus(7);
        modelShip.setStatusName(dictService.findDictLabel("MODEL_SHIP_PROCESS_STATUS", "7"));
        this.updateModelShip(modelShip);
        //获取上一结点完成时间
        LambdaQueryWrapper<ModelShipProcess> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ModelShipProcess::getDeletedFlg, 0);
        queryWrapper.eq(ModelShipProcess::getProcessStatus, 5);
        queryWrapper.eq(ModelShipProcess::getShipId, modelShip.getId());
        ModelShipProcess lastProc = modelShipProcessMapper.selectOne(queryWrapper);
        //添加加工过程
        ModelShipProcess proc = new ModelShipProcess();
        proc.setShipId(modelShip.getId());
        proc.setShipCode(modelShip.getShipCode());
        proc.setStartDate(lastProc.getEndDate());
        proc.setEndDate(params.getModRepairTime());
        proc.setProcessStatus(6);
        proc.setItem("修模");
        proc.setOperator(params.getModRepairOperator());
        User user = userService.findById(params.getModRepairOperator());
        if(user != null){
            proc.setOperatorName(user.getUname());
        }
        modelShipProcessMapper.insert(proc);
    }

    /**
     * 油漆
     * @param params
     */
    @Override
    @Transactional
    public void paint(ShipModelProcParams params){
        //根据id获取船模信息
        ModelShip modelShip = this.baseMapper.selectById(params.getId());
        modelShip.setStatus(8);
        modelShip.setStatusName(dictService.findDictLabel("MODEL_SHIP_PROCESS_STATUS", "8"));
        this.updateModelShip(modelShip);
        //获取上一结点完成时间
        LambdaQueryWrapper<ModelShipProcess> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ModelShipProcess::getDeletedFlg, 0);
        queryWrapper.eq(ModelShipProcess::getProcessStatus, 6);
        queryWrapper.eq(ModelShipProcess::getShipId, modelShip.getId());
        ModelShipProcess lastProc = modelShipProcessMapper.selectOne(queryWrapper);
        //添加加工过程
        ModelShipProcess proc = new ModelShipProcess();
        proc.setShipId(modelShip.getId());
        proc.setShipCode(modelShip.getShipCode());
        proc.setStartDate(lastProc.getEndDate());
        proc.setEndDate(params.getPaintTime());
        proc.setProcessStatus(7);
        proc.setItem("油漆");
        proc.setOperator(params.getPaintOperator());
        User user = userService.findById(params.getPaintOperator());
        if(user != null){
            proc.setOperatorName(user.getUname());
        }
        modelShipProcessMapper.insert(proc);
    }

    /**
     * 完成
     * @param params
     */
    @Override
    @Transactional
    public void finish(ShipModelProcParams params){
        //根据id获取船模信息
        ModelShip modelShip = this.baseMapper.selectById(params.getId());
        modelShip.setStatus(9);
        modelShip.setStatusName(dictService.findDictLabel("MODEL_SHIP_PROCESS_STATUS", "9"));
        modelShip.setActuallyEnddate(params.getFinishTime());
        this.updateModelShip(modelShip);
        //获取上一结点完成时间
        LambdaQueryWrapper<ModelShipProcess> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ModelShipProcess::getDeletedFlg, 0);
        queryWrapper.eq(ModelShipProcess::getProcessStatus, 7);
        queryWrapper.eq(ModelShipProcess::getShipId, modelShip.getId());
        ModelShipProcess lastProc = modelShipProcessMapper.selectOne(queryWrapper);
        //添加加工过程
        ModelShipProcess proc = new ModelShipProcess();
        proc.setShipId(modelShip.getId());
        proc.setShipCode(modelShip.getShipCode());
        proc.setStartDate(lastProc.getEndDate());
        proc.setEndDate(params.getFinishTime());
        proc.setProcessStatus(8);
        proc.setItem("已完成");
        proc.setOperator(params.getOperator());
        User user = userService.findById(params.getOperator());
        if(user != null){
            proc.setOperatorName(user.getUname());
        }
        modelShipProcessMapper.insert(proc);
        //添加检验情况
        ModelShipTest test = params.getTest();
        if(test != null){
            test.setShipId(modelShip.getId());
            test.setShipCode(modelShip.getShipCode());
            modelShipTestMapper.insert(test);
        }
    }

    @Override
    public List<ModelShipProcess> getModelShipProcsByShipId(String shipId){
        LambdaQueryWrapper<ModelShipProcess> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ModelShipProcess::getDeletedFlg, 0);
        queryWrapper.eq(ModelShipProcess::getShipId, shipId);
        queryWrapper.orderByDesc(ModelShipProcess::getCreatedTime);
        List<ModelShipProcess> procs = modelShipProcessMapper.selectList(queryWrapper);
        return procs;
    }

    @Override
    public List<ModelShipProcsVO> getModelShipProcsVOByShipId(String shipId){
        LambdaQueryWrapper<ModelShipProcess> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ModelShipProcess::getDeletedFlg, 0);
        queryWrapper.eq(ModelShipProcess::getShipId, shipId);
        queryWrapper.orderByDesc(ModelShipProcess::getCreatedTime);
        List<ModelShipProcess> procs = modelShipProcessMapper.selectList(queryWrapper);
        List<ModelShipProcsVO> procsList = new ArrayList<ModelShipProcsVO>();
        if(CollectionUtil.isNotEmpty(procs)){
            for(ModelShipProcess proc : procs){
                ModelShipProcsVO vo = new ModelShipProcsVO();
                vo.setAction(proc.getItem() + " " + proc.getOperatorName());
                if("开始".equals(proc.getItem())){
                    vo.setEndDate(proc.getStartDate());
                }else{
                    vo.setEndDate(proc.getEndDate());
                }
                procsList.add(vo);
            }

        }
        return procsList;
    }

    @Override
    public List<FileParams> getModelShipAttachsByShipId(String shipId){
        LambdaQueryWrapper<AttachmentFile> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AttachmentFile::getDeletedFlg, 0);
        queryWrapper.eq(AttachmentFile::getVoucherCode, shipId);
        queryWrapper.eq(AttachmentFile::getVoucherType, "4");
        queryWrapper.orderByDesc(AttachmentFile::getCreatedTime);
        List<AttachmentFile> attachs = attachmentFileMapper.selectList(queryWrapper);
        List<FileParams> files = new ArrayList<>();
        if(CollectionUtil.isNotEmpty(attachs)){
            for(AttachmentFile attach : attachs){
                FileParams file = new FileParams();
                file.setFileName(attach.getFilename());
                file.setFilePath(attach.getFilepath());
                files.add(file);
            }
        }
        return files;
    }

    @Override
    public ModelShipTest getModelShipTestByShipId(String shipId){
        LambdaQueryWrapper<ModelShipTest> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ModelShipTest::getDeletedFlg, 0);
        queryWrapper.eq(ModelShipTest::getShipId, shipId);
        List<ModelShipTest> list = modelShipTestMapper.selectList(queryWrapper);
        ModelShipTest test = new ModelShipTest();
        if(CollectionUtil.isNotEmpty(list)){
            test = list.get(0);
        }
        return test;
    }

    /**
     * 获取项目列表
     * @return
     */
    @Override
    public List<ProjectVO> getProjectList(){
        //获取当前用户id
        ProjectManager pm = new ProjectManager();
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        boolean isSysAdmin = isSysAdmin(user.getUserId());
        if(isSysAdmin){
            pm.setUserId(null);
        }else{
            pm.setUserId(user.getUserId());
        }
        List<ProjectManager> pmList = projectManagerService.findProjectManagerList(pm);
        List<String> projCodes = pmList.stream().map(ProjectManager::getProjectCode).collect(Collectors.toList());
        List<ProjectVO> projVOList = new ArrayList<ProjectVO>();
        if(CollectionUtil.isNotEmpty(projCodes)){
            SypqProject projParams = new SypqProject();
            List<SypqProject> projList = projectService.findSypqProjectList(projParams);
            if(CollectionUtil.isNotEmpty(projList)){
                for(SypqProject proj : projList){
                    if(projCodes.contains(proj.getProjectCode())){
                        ProjectVO vo = new ProjectVO();
                        BeanUtil.copyProperties(proj, vo);
                        projVOList.add(vo);
                    }
                }
            }
        }
        return projVOList;
    }

    /**
     * 导出船模加工申请表
     * @param id
     * @param response
     */
    @Override
    public void expApplyForm(String id,  HttpServletResponse response){
        ModelShip modelShip = this.findModelShipById(id);
        Map<String, Object> map = new HashMap<String, Object>();
        String directoryName = UploadPathUtil.getRootPath() + "export/" + UUID.randomUUID();
        File file = new File(directoryName);
        if (file.exists()) {//如果存在,此uuid生成的文件名被使用,重新生成
            expApplyForm(id, response);
        }
        file.mkdirs();
        if(modelShip != null){
            //项目编号
            map.put("projectCode", modelShip.getProjectCode());
            //项目主持（项目经理）
            String projectCode = modelShip.getProjectCode();
            String projectManager = "";
            SypqProjectDto projectDto = new SypqProjectDto();
            projectDto.setProjectCode(projectCode);
            List<SypqProjectDto> projList = projectMapper.getProjectDetail(projectDto, "");
            if(CollectionUtil.isNotEmpty(projList)){
                SypqProjectDto proj = projList.get(0);
                if(proj != null){
                    projectManager = proj.getManagers();
                }
            }
            map.put("projectManager", projectManager);

            //船模编号
            map.put("shipCode", modelShip.getShipCode());
            //缩尺比
            map.put("rate", modelShip.getRate());
            //船舶类型
            map.put("shipType", modelShip.getShipTypeName());
            //船模类型
            map.put("modelType", modelShip.getModelTypeName());
            //申请日期
            map.put("applyDate", DateUtil.getDateFormat(modelShip.getApplyDate(), "yyyy年MM月dd日"));
            //要求完成日期
            map.put("demandEnddate", DateUtil.getDateFormat(modelShip.getDemandEnddate(), "yyyy年MM月dd日"));
            //总长-实船
            map.put("lengthOrigal", modelShip.getLengthOrigal());
            //总长-模型
            map.put("lengthModel", modelShip.getLengthModel());
            //两柱之间-实船
            map.put("columnWidthOrigal", modelShip.getColumnWidthOrigal());
            //两柱之间-模型
            map.put("columnWidthModel", modelShip.getColumnWidthModel());
            //型宽-实船
            map.put("widthOrigal", modelShip.getWidthOrigal());
            //型宽-模型
            map.put("widthModel", modelShip.getWidthModel());
            //设计吃水-实船
            map.put("waterDeepOrigal", modelShip.getWaterDeepOrigal());
            //设计吃水-模型
            map.put("waterDeepModel", modelShip.getWaterDeepModel());
            //型深-实船
            map.put("bodyDeepOrigal", modelShip.getBodyDeepOrigal());
            //型深-模型
            map.put("bodyDeepModel", modelShip.getBodyDeepModel());
            //轴高-实船
            map.put("axieHightOrigal", modelShip.getAxieHightOrigal());
            //轴高-模型
            map.put("axieHightModel", modelShip.getAxieHightModel());
            //轴间距-实船
            map.put("axieWidthOrigal", modelShip.getAxieWidthOrigal());
            //轴间距-模型
            map.put("axieWidthModel", modelShip.getAxieWidthModel());
            //方形系数
            map.put("rectRate", modelShip.getRectRate());
            //板块数
            map.put("blockNumber", modelShip.getBlockNumber());
            //重量要求
            map.put("weight", modelShip.getWeight());
            //首部升高
            map.put("headHeight", modelShip.getHeadHeight());
            //尾部升高
            map.put("tailHeight", modelShip.getTailHeight());
            //首侧推
            map.put("headPush", modelShip.getHeadPush());
            //尾侧推
            map.put("tailPush", modelShip.getTailPush());
            //备注
            map.put("memo", modelShip.getMemo());

            //加载模板
            org.springframework.core.io.Resource resource = new ClassPathResource("docTemplate/cmjgsqb.docx");

            InputStream inputStream = null;
            try {
                inputStream = resource.getInputStream();
                String fileName = modelShip.getShipCode() + ".docx";
                //是否导出为pdf
                boolean isPdf = false;
                WordUtils.generateWord(map, inputStream, directoryName, fileName, isPdf);
                if(isPdf){
                    fileName = fileName.substring(0, fileName.lastIndexOf(".")) + ".pdf";
                }
                FileInputStream in = new FileInputStream(new File(directoryName + "/" + fileName));
                response.setCharacterEncoding("UTF-8");
                response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
                response.setContentType("application/octet-stream;charset=UTF-8");
                OutputStream out = response.getOutputStream();

                IOUtils.copy(in, out);
                out.flush();
                out.close();
                in.close();
            } catch (IOException e) {
                log.error(e.getMessage(), e);
            }
            //删除文件生成临时目录
//            WordUtils.deleteFile(directoryName);
        }

    }

    /**
     * 导出船模质量检验表
     * @param id
     * @param response
     */
    @Override
    public void expShipModelCheckForm(String id,  HttpServletResponse response){
        LambdaQueryWrapper<ModelShipTest> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ModelShipTest::getDeletedFlg, 0);
        queryWrapper.eq(ModelShipTest::getShipId, id);
        ModelShipTest test = modelShipTestMapper.selectOne(queryWrapper);
        Map<String, Object> map = new HashMap<String, Object>();
        String directoryName = UploadPathUtil.getRootPath() + "export/" + UUID.randomUUID();
        File file = new File(directoryName);
        if (file.exists()) {//如果存在,此uuid生成的文件名被使用,重新生成
            expShipModelCheckForm(id, response);
        }
        file.mkdirs();
        if(test != null){
            DecimalFormat df = new DecimalFormat("#.####");
            df.setGroupingUsed(false);
            //将对象转成map
            map = BeanUtil.beanToMap(test);
            map.put("paintSmoothRes", test.getPaintSmoothRes() == 1 ? "是" : "否" );
            map.put("paintSurveyRes", test.getPaintSurveyRes() == 1 ? "是" : "否" );
            map.put("stationMarkRes", test.getStationMarkRes() == 1 ? "是" : "否" );

            map.put("lbpError", df.format(test.getLbpError()));
            map.put("smwError", df.format(test.getSmwError()));
            map.put("smahError", df.format(test.getSmahError()));
            map.put("smawError", df.format(test.getSmawError()));
            map.put("smtcbRes", df.format(test.getSmtcbRes()));
            map.put("bslcpRes", df.format(test.getBslcpRes()));

            //加载模板
            org.springframework.core.io.Resource resource = new ClassPathResource("docTemplate/cmzljyb.docx");

            InputStream inputStream = null;
            try {
                inputStream = resource.getInputStream();
                String fileName = test.getShipCode() + "checkForm.docx";
                //是否导出为pdf
                boolean isPdf = false;
                WordUtils.generateWord(map, inputStream, directoryName, fileName, isPdf);
                if(isPdf){
                    fileName = fileName.substring(0, fileName.lastIndexOf(".")) + ".pdf";
                }
                FileInputStream in = new FileInputStream(new File(directoryName + "/" + fileName));
                response.setCharacterEncoding("UTF-8");
                response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
                response.setContentType("application/octet-stream;charset=UTF-8");
                OutputStream out = response.getOutputStream();

                IOUtils.copy(in, out);
                out.flush();
                out.close();
                in.close();
            } catch (IOException e) {
                log.error(e.getMessage(), e);
            }
            //删除文件生成临时目录
//            WordUtils.deleteFile(directoryName);
        }
    }

    /**
     * 导出船模加工进度及检验表
     * @param id
     * @param response
     */
    @Override
    public void expProcForm(String id,  HttpServletResponse response){
        //加工过程
        List<ModelShipProcess> procList = this.getModelShipProcsByShipId(id);
        Map<Integer, ModelShipProcess> procsMap = procList.stream().collect(Collectors.toMap(ModelShipProcess::getProcessStatus, proc ->proc));
//船模信息
        ModelShip modelShip = this.findModelShipById(id);
        Map<String, Object> map = new HashMap<String, Object>();
        if(procsMap != null){
            map.put("shipCode", modelShip.getShipCode());
            map.put("projCode", modelShip.getProjectCode());
            //上传图纸
            ModelShipProcess proc2 = procsMap.get(2);
            map.put("proc2Oprator", proc2.getOperatorName());
            map.put("proc2Start", proc2.getStartDate() == null ? "" : DateUtil.getDateFormat(proc2.getStartDate(), "yyyy年MM月dd日"));
            map.put("proc2End",  proc2.getEndDate() == null ? "" :DateUtil.getDateFormat(proc2.getEndDate(), "yyyy年MM月dd日"));
            //下料
            ModelShipProcess proc3 = procsMap.get(3);
            map.put("proc3Oprator", proc3.getOperatorName());
            map.put("proc3Start", proc3.getStartDate() == null ? "" : DateUtil.getDateFormat(proc3.getStartDate(), "yyyy年MM月dd日"));
            map.put("proc3End", proc3.getEndDate() == null ? "" : DateUtil.getDateFormat(proc3.getEndDate(), "yyyy年MM月dd日"));
            //粗切
            ModelShipProcess proc4 = procsMap.get(4);
            map.put("proc4Oprator", proc4.getOperatorName());
            map.put("proc4Start", proc4.getStartDate() == null ? "" : DateUtil.getDateFormat(proc4.getStartDate(), "yyyy年MM月dd日"));
            map.put("proc4End", proc4.getEndDate() == null ? "" : DateUtil.getDateFormat(proc4.getEndDate(), "yyyy年MM月dd日"));
            //精切
            ModelShipProcess proc5 = procsMap.get(5);
            map.put("proc5Oprator", proc5.getOperatorName());
            map.put("proc5Start", proc5.getStartDate() == null ? "" : DateUtil.getDateFormat(proc5.getStartDate(), "yyyy年MM月dd日"));
            map.put("proc5End",  proc5.getEndDate() == null ? "" : DateUtil.getDateFormat(proc5.getEndDate(), "yyyy年MM月dd日"));
            //修模
            ModelShipProcess proc6 = procsMap.get(6);
            map.put("proc6Oprator", proc6.getOperatorName());
            map.put("proc6Start", proc6.getStartDate() == null ? "" : DateUtil.getDateFormat(proc6.getStartDate(), "yyyy年MM月dd日"));
            map.put("proc6End", proc6.getEndDate() == null ? "" : DateUtil.getDateFormat(proc6.getEndDate(), "yyyy年MM月dd日"));
            //油漆
            ModelShipProcess proc7 = procsMap.get(7);
            map.put("proc7Oprator", proc7.getOperatorName());
            map.put("proc7Start", proc7.getStartDate() == null ? "" : DateUtil.getDateFormat(proc7.getStartDate(), "yyyy年MM月dd日"));
            map.put("proc7End", proc7.getEndDate() == null ? "" : DateUtil.getDateFormat(proc7.getEndDate(), "yyyy年MM月dd日"));

            String directoryName = UploadPathUtil.getRootPath() + "export/" + UUID.randomUUID();
            File file = new File(directoryName);
            if (file.exists()) {//如果存在,此uuid生成的文件名被使用,重新生成
                expProcForm(id, response);
            }
            file.mkdirs();
            //加载模板
            org.springframework.core.io.Resource resource = new ClassPathResource("docTemplate/cmjgjdjjyb.docx");

            InputStream inputStream = null;
            try {
                inputStream = resource.getInputStream();
                String fileName = proc2.getShipCode() + "procForm.docx";
                //是否导出为pdf
                boolean isPdf = false;
                WordUtils.generateWord(map, inputStream, directoryName, fileName, isPdf);
                if(isPdf){
                    fileName = fileName.substring(0, fileName.lastIndexOf(".")) + ".pdf";
                }
                FileInputStream in = new FileInputStream(new File(directoryName + "/" + fileName));
                response.setCharacterEncoding("UTF-8");
                response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
                response.setContentType("application/octet-stream;charset=UTF-8");
                OutputStream out = response.getOutputStream();

                IOUtils.copy(in, out);
                out.flush();
                out.close();
                in.close();
            } catch (IOException e) {
                log.error(e.getMessage(), e);
            }
//            WordUtils.deleteFile(directoryName);
        }
    }

    /**
     * 获取企业微信端船模列表
     * @param params
     * @return
     */
    @Override
    public List<WechatShipModelVO> getShipModelList(WechatModelParams params){
        LambdaQueryWrapper<ModelShip> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ModelShip::getDeletedFlg, 0);
        queryWrapper.orderByDesc(ModelShip::getCreatedTime);
        //根据来源查询
        if(null != params.getSourceType()){
            queryWrapper.eq(ModelShip::getSource, params.getSourceType());
        }
        //根据状态查询
        if(null != params.getStatus()){
            List statusList = null;
            if(params.getStatus() == 1){
                statusList = Collections.singletonList(1);
            }else if(params.getStatus() == 2){
                statusList = Arrays.asList(2,3,4,5,6,7,8);
            }else if(params.getStatus() == 3){
                statusList = Collections.singletonList(9);
            }else{
                statusList = Arrays.asList(1,2,3,4,5,6,7,8,9);
            }
            queryWrapper.in(ModelShip::getStatus, statusList);
        }

        //角色判断
        CurUserProjInfoVO curUserProjInfoVO = getCurUserProjInfo();
        boolean isSysAdmin = curUserProjInfoVO.isSysAdmin();
        List<String> projCodeList = curUserProjInfoVO.getProjCodeList();
        //根据权限判断可以查看的项目相关的桨模
        if(!isSysAdmin){
            if(CollectionUtil.isNotEmpty(projCodeList)){
                queryWrapper.in(ModelShip::getProjectCode, projCodeList);
            }else{
                projCodeList.add("0");
                queryWrapper.in(ModelShip::getProjectCode, projCodeList);
            }
        }

        List<ModelShip> modelShipList = this.baseMapper.selectList(queryWrapper);
        List<WechatShipModelVO> voList = new ArrayList<WechatShipModelVO>();
        if(CollectionUtil.isNotEmpty(modelShipList)){
            for(ModelShip modelShip : modelShipList){
                WechatShipModelVO vo = new WechatShipModelVO();
                BeanUtil.copyProperties(modelShip, vo);
                //获取项目经理
                String projectCode = modelShip.getProjectCode();
                SypqProjectDto projectDto = new SypqProjectDto();
                projectDto.setProjectCode(projectCode);
                List<SypqProjectDto> projList = projectMapper.getProjectDetail(projectDto, "");
                if(CollectionUtil.isNotEmpty(projList)){
                    SypqProjectDto proj = projList.get(0);
                    if(proj != null){
                        vo.setProjectManager(proj.getManagers());
                    }
                }
                //附件
                List<FileParams> fileList = this.getModelShipAttachsByShipId(vo.getId());
                vo.setFileList(fileList);
                voList.add(vo);
            }
        }
        return voList;
    }

    /**
     * 角色判断
     * @return
     */
    private CurUserProjInfoVO getCurUserProjInfo(){
        List<String> projCodeList = new ArrayList<String>();
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        List<UserRole> userRoles = userRoleService.getUserRoleListByUserid(user.getUserId());
        boolean isSysAdmin = false;

        boolean isOperator = false;

        if(CollectionUtil.isNotEmpty(userRoles)){
            //判断是否系统管理员
            isSysAdmin = userRoles.stream().anyMatch(userRole -> Objects.equals(userRole.getRoleId(), "1"));
            //判断是否资源管理员
            boolean isResourceAdmin = userRoles.stream().anyMatch(userRole -> Objects.equals(userRole.getRoleId(), "c2331034b20a380bf860b331cdd12619"));
            //判断是否操作员/检验员
            isOperator = userRoles.stream().anyMatch(userRole -> Objects.equals(userRole.getRoleId(), "533f1044ed1db628316a3e7c35305fd8"));
            if(isResourceAdmin){
                List<String> taskProjList = taskMapper.getTaskByRsAdmin(user.getUserId());
                projCodeList.addAll(taskProjList);
            }
        }
        //项目审批人的项目
        SypqProject sypqProject = new SypqProject();
        sypqProject.setAuditorid(user.getUserId());
        List<SypqProject> projs = projectService.findSypqProjectList(sypqProject);
        if(CollectionUtil.isNotEmpty(projs)){
            List<String> auditProjCodeList = projs.stream().map(SypqProject::getProjectCode).collect(Collectors.toList());
            projCodeList.addAll(auditProjCodeList);
        }
        //项目经理的项目
        ProjectManager pm = new ProjectManager();
        pm.setUserId(user.getUserId());
        List<ProjectManager> pmList = projectManagerService.findProjectManagerList(pm);
        List<String> projCodes = pmList.stream().map(ProjectManager::getProjectCode).collect(Collectors.toList());
        if(CollectionUtil.isNotEmpty(projCodes)){
            projCodeList.addAll(projCodes);
        }
        CurUserProjInfoVO vo = new CurUserProjInfoVO();
        //操作员（实验员）也可以查看所有船模数据
        vo.setSysAdmin(isSysAdmin || isOperator);
        vo.setProjCodeList(projCodeList);

        return vo;
    }

    /**
     * 判断是否系统管理员
     * @param userId
     * @return
     */
    private boolean isSysAdmin(String userId){
        List<UserRole> userRoles = userRoleService.getUserRoleListByUserid(userId);
        boolean isSysAdmin = false;
        if(CollectionUtil.isNotEmpty(userRoles)){
            //判断是否系统管理员
            isSysAdmin = userRoles.stream().anyMatch(userRole -> Objects.equals(userRole.getRoleId(), "1"));

            }
            return isSysAdmin;
    }
}
